package com.raft.kvstore.message;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.UUID;

import com.alibaba.com.caucho.hessian.io.HessianInput;
import com.alibaba.com.caucho.hessian.io.HessianOutput;

/**set请求
 * @author zhangsulei
 *
 */
public class SetCommand implements Serializable {

    /**
	 *
	 */
	private static final long serialVersionUID = 6570371306406788292L;
	private final String requestId;
    private final String key;
    private final byte[] value;

    public SetCommand(String key, byte[] value) {
        this(UUID.randomUUID().toString(), key, value);
    }

    /**
     * @param requestId 唯一id，用于关联请求、set命令和客户端
     * @param key
     * @param value
     */
    public SetCommand(String requestId, String key, byte[] value) {
        this.requestId = requestId;
        this.key = key;
        this.value = value;
    }

    public static SetCommand fromBytes(byte[] bytes) {
        try {
        	SetCommand setCommand = decode(bytes, SetCommand.class);
            return setCommand;
        } catch (Exception e) {
            throw new IllegalStateException("failed to deserialize set command", e);
        }
    }

    public String getRequestId() {
        return requestId;
    }

    public String getKey() {
        return key;
    }

    public byte[] getValue() {
        return value;
    }

    public byte[] toBytes() {
    	ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
        HessianOutput hessianOutput = new HessianOutput(byteOutput);
        try {
			hessianOutput.writeObject(this);
		} catch (IOException e) {
			e.printStackTrace();
		}
        return byteOutput.toByteArray();
    }

    @Override
    public String toString() {
        return "SetCommand{key='" + key + "', requestId='" + requestId + "'}";
    }

    private static <T extends Serializable> T decode(byte[] bytes, Class<T> clazz) {
        if (bytes == null) {
            return null;
        }
        // 1、将字节数组转换成字节输入流
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);

        // step 1. 定义外部序列化工厂
        //ExtSerializerFactory extSerializerFactory = new ExtSerializerFactory();
        //extSerializerFactory.addSerializer(java.time.OffsetDateTime.class, new OffsetDateTimeRedisSerializer());
        //extSerializerFactory.addDeserializer(java.time.OffsetDateTime.class, new OffsetDateTimeRedisDeserializer());
        // step 2. 序列化工厂
        //SerializerFactory serializerFactory = new SerializerFactory();
        //serializerFactory.addFactory(extSerializerFactory);
        HessianInput hessianInput = new HessianInput(bis);
        //hessianInput.setSerializerFactory(serializerFactory);
        Object object = null;

        try {
            object = hessianInput.readObject();
        } catch (IOException e) {
        	e.printStackTrace();
        } catch (Exception e) {
        	e.printStackTrace();
        }

        return (T) object;
    }

}
